<?php

namespace app\admin\service;

use app\admin\common\ServiceResponse;
use think\facade\Db;
use app\common\ExchangeRateHostAPI;
use app\admin\model\Operator as OperatorModel;
use app\admin\model\Order as OrderModel;

class Index extends BaseService
{

    protected $operate;

    use ServiceResponse;
    public function __construct()
    {
        parent::__construct();
        $this->operate = [
            '订单-编辑',            // order         order
            '订单-部分发货申请发起', // order          order_part_delivery_apply
            '订单-支付凭证上传',     // order         order_payment
            '退货退款单-创建',      // returnorder    returnorder
            '发票-创建',            // invoice       invoice
            '采购付款单-创建',      // purchase_order purchase_payment_order
            '库存-调拨发起',        // inventory      logistics_order
            '库存-校对发起',        // inventory      inventory
            '订单-撤销编辑',
            '订单-部分发货申请撤销',
            '订单-支付凭证撤销',
            '退货退款单-撤销',
            '发票-撤销',
            '采购付款单-撤销',
            '库存-调拨撤销',
            '库存-校对撤销',
        ];
    }
    /**
     * @describe 订单排行榜
     * @author: Bobo
     * @date: 2025-09-10 15:17:53
     * @param int $time_period
     * @param int $operator_id 操作员id
     * @return Renderable
     */
    public function OrderRanking(int $time_period, int $operator_id)
    {

        $operator = Db::name('operator')
            ->where('id', $operator_id)
            ->find();
        $query = Db::name('order')
            ->where('is_del', 0)
            ->where('order_type', '<>', 2)
            ->where('pay_amount', '>', 0);

        if (1 == $time_period) { // 昨天
            $query->where('create_time', '>=', date('Y-m-d H:i:s', strtotime('-1 day')))
                ->where('create_time', '<=', date('Y-m-d H:i:s'));
        } else { //当月
            $query->where('create_time', '>=', date('Y-m-d H:i:s', strtotime('-1 month')))
                ->where('create_time', '<=', date('Y-m-d H:i:s'));
        }

        $all_owner_ids = [];

        // 获取数量统计
        $quantity_stats = (clone $query)
            ->field('count(id) as amount, owner')
            ->group('owner')
            ->select()
            ->toArray();

        if (!empty($quantity_stats)) {
            $all_owner_ids = array_unique(array_column($quantity_stats, 'owner'));
        }

        // 获取金额统计（按货币分组）
        $amount_stats = (clone $query)
            ->field('sum(pay_amount) as amount, owner, currency')
            ->group('owner,currency')
            ->select()
            ->toArray();

        if (!empty($amount_stats)) {
            $all_owner_ids = array_unique(array_merge($all_owner_ids, array_unique(array_column($amount_stats, 'owner'))));
        }

        $all_owner = Db::name('operator')
            ->whereIn('id', $all_owner_ids)
            ->field('id,cname')
            ->select()
            ->toArray();
        $all_owner = array_column($all_owner, 'cname', 'id');

        // 获取汇率 API 实例
        $fetcher = new ExchangeRateHostAPI();

        // 汇率转换（假设已经在配置中设置）
        $usd_to_cny_rate = $fetcher->getRate('USD', 'CNY'); // USD to CNY exchange rate
        $cny_to_usd_rate = $fetcher->getRate('CNY', 'USD');

        if (!is_numeric($usd_to_cny_rate) || !is_numeric($cny_to_usd_rate)) {
            return $this->error('汇率获取失败');
        }

        $usd_data = [];
        $cny_data = [];

        foreach ($amount_stats as $stat) {
            $owner = $all_owner[$stat['owner']] ?? '';
            $amount = $stat['amount'];

            if ($stat['currency'] == 214) { // USD
                // 原USD金额
                if (!isset($usd_data[$owner])) {
                    $usd_data[$owner] = 0;
                }
                $usd_data[$owner] += $amount;

                // 转换为CNY
                if (!isset($cny_data[$owner])) {
                    $cny_data[$owner] = 0;
                }
                $cny_data[$owner] += ($amount * $usd_to_cny_rate);
            } elseif ($stat['currency'] == 4) { // CNY
                // 转换为USD
                if (!isset($usd_data[$owner])) {
                    $usd_data[$owner] = 0;
                }
                $usd_data[$owner] += ($amount * $cny_to_usd_rate);

                // 原CNY金额
                if (!isset($cny_data[$owner])) {
                    $cny_data[$owner] = 0;
                }
                $cny_data[$owner] += $amount;
            }
        }


        $is_allow_display_amount = isSuperAdmin($operator_id);

        if (!$is_allow_display_amount) {
            $operator_job = explode(',', $operator['job']);
            if (in_array(1, $operator_job) || in_array(10, $operator_job)) {
                $is_allow_display_amount = true;
            }
        }
        // 组合每个负责人在USD/CNY的金额，并按人民币金额排序
        $owners = array_unique(array_merge(array_keys($usd_data), array_keys($cny_data)));
        $amount_list = [];
        // 总人民币金额（用于percent）
        $total_cny_amount = 0.0;
        foreach ($owners as $ownerName) {
            $amount_usd = isset($usd_data[$ownerName]) ? (float)$usd_data[$ownerName] : 0.0;
            $amount_cny = isset($cny_data[$ownerName]) ? (float)$cny_data[$ownerName] : 0.0;
            $total_cny_amount += $amount_cny;

            $amount_list[] = [
                'ranking' => 0,
                'amount_usd' => round($amount_usd, 2),
                'amount_cny' => round($amount_cny, 2),
                'percent' => '',
                'name' => $ownerName,
            ];
        }
        usort($amount_list, function ($a, $b) {
            return $b['amount_cny'] <=> $a['amount_cny'];
        });
        foreach ($amount_list as $index => &$row) {
            $row['ranking'] = $index + 1;
            $row['percent'] = $total_cny_amount > 0 ? (round(($row['amount_cny'] / $total_cny_amount) * 100, 2) . '%') : '0%';
            $row['amount_usd'] = $is_allow_display_amount ? $row['amount_usd'] : '*';
            $row['amount_cny'] = $is_allow_display_amount ? $row['amount_cny'] : '*';
        }
        unset($row);

        // 格式化并排序数量统计
        $quantity_list = [];
        foreach ($quantity_stats as $stat) {
            $owner = $all_owner[$stat['owner']] ?? '';
            $quantity_list[$owner] = $stat['amount'];
        }
        // 统计总数量用于percent
        $quantity_total = array_sum($quantity_list);
        // 转换为列表并按数量排序
        $quantity_rows = [];
        foreach ($quantity_list as $name => $qty) {
            $quantity_rows[] = [
                'ranking' => 0,
                'amount' => (int)$qty,
                'name' => (string)$name,
                'percent' => '',
            ];
        }
        usort($quantity_rows, function ($a, $b) {
            return $b['amount'] <=> $a['amount'];
        });
        foreach ($quantity_rows as $index => &$row) {
            $row['ranking'] = $index + 1;
            $row['percent'] = $quantity_total > 0 ? (round(($row['amount'] / $quantity_total) * 100, 2) . '%') : '0%';
        }
        unset($row);

        // 组装最终结果
        $result = [
            'amount' => [
                'list' => $amount_list,
                'total' => count($amount_list)
            ],
            'quantity' => [
                'list' => $quantity_rows,
                'total' => count($quantity_rows)
            ]
        ];

        return $this->success($result);
    }

    /**
     * @describe 订单统计
     * @author: Bobo
     * @date: 2025-09-10 15:49:13
     * @return Renderable
     */
    public function OrderStatistics()
    {
        // 获取总数量
        $total_quantity = Db::name('order')
            ->where('is_del', 0)
            ->where('order_type', '<>', 2)
            ->where('pay_amount', '>', 0)
            ->count();

        // 获取总金额（按来源与货币分组）
        $amount_stats = Db::name('order')
            ->where('is_del', 0)
            ->where('order_type', '<>', 2)
            ->where('pay_amount', '>', 0)
            ->field('sum(pay_amount) as amount, source, currency')
            ->group('source,currency')
            ->select()
            ->toArray();


        // 获取汇率
        $fetcher = new ExchangeRateHostAPI();
        $usd_to_cny_rate = $fetcher->getRate('USD', 'CNY');
        $cny_to_usd_rate = $fetcher->getRate('CNY', 'USD');

        if (!is_numeric($usd_to_cny_rate) || !is_numeric($cny_to_usd_rate)) {
            return $this->error('汇率获取失败');
        }
        $orderModel = new OrderModel();
        $sourceList = $orderModel->getStaticAttr()['source'];
        // 计算每个来源的金额，并按来源内进行货币换算后再汇总
        $per_source_totals = [];
        foreach ($amount_stats as $stat) {
            $source = $stat['source'] ?? 'unknown';
            if (!isset($per_source_totals[$source])) {
                $per_source_totals[$source] = ['usd_total_amount' => 0.0, 'cny_total_amount' => 0.0];
                $per_source_totals[$source]['source'] =  $sourceList[$source] ?? 'unknown';
                $per_source_totals[$source]['total_qty'] = 0;
            }
            $per_source_totals[$source]['total_qty']++;
            if ($stat['currency'] == 214) { // USD
                $per_source_totals[$source]['usd_total_amount'] += (float)$stat['amount'];
                $per_source_totals[$source]['cny_total_amount'] += (float)$stat['amount'] * $usd_to_cny_rate; // USD -> CNY
            } elseif ($stat['currency'] == 4) { // CNY
                $per_source_totals[$source]['cny_total_amount'] += (float)$stat['amount'];
                $per_source_totals[$source]['usd_total_amount'] += (float)$stat['amount'] * $cny_to_usd_rate; // CNY -> USD
            }
        }

        // 四舍五入每个来源的 usd/cny 到 2 位小数
        foreach ($per_source_totals as &$item) {
            $item['usd_total_amount'] = round($item['usd_total_amount'], 2);
            $item['cny_total_amount'] = round($item['cny_total_amount'], 2);
        }
        unset($item);

        // 按 total_qty 从高到低排序
        uasort($per_source_totals, function ($a, $b) {
            return $b['total_qty'] <=> $a['total_qty'];
        });

        // 返回有序列表，避免 JSON 对象键导致的无序问题
        $per_source_list = array_values($per_source_totals);

        return $this->success($per_source_list);
    }

    /**
     * 格式化并排序数据
     * @param array $data 原始数据
     * @param string $nameField 名称字段
     * @param bool $roundAmount 是否对金额进行四舍五入
     * @return array 格式化后的数据
     */
    private function formatAndSortData(array $data, string $nameField = 'name', bool $roundAmount = true): array
    {
        $formatted = [];
        foreach ($data as $key => $value) {
            $formatted[] = [
                'ranking' => 0,
                'amount' => $roundAmount ? round($value, 2) : (int)$value,
                $nameField => (string)$key
            ];
        }

        // 按金额降序排序
        usort($formatted, function ($a, $b) {
            return $b['amount'] <=> $a['amount'];
        });

        // 添加排名
        foreach ($formatted as $index => &$item) {
            $item['ranking'] = $index + 1;
        }

        return $formatted;
    }

    /**
     * @describe 待办列表
     * @author: Bobo
     * @date: 2025-09-10 18:19:50
     * @param int $operator_id 操作员id
     * @return Renderable
     */
    public function ToDo(int $operator_id, int $pageIndex, int $pageSize)
    {
        $job = Db::name('operator')
            ->where('id', $operator_id)
            ->value('job');

        $query = Db::name('business_log')
            ->where('operate', 'in', $this->operate)
            ->where(function ($query) use ($operator_id, $job) {
                $query->where('user_id', $operator_id);
                if (!empty($job)) {
                    $jobIds = explode(',', $job);
                    foreach ($jobIds as $jobId) {
                        if (!empty($jobId)) {
                            $query->whereOr(function ($q) use ($jobId) {
                                $q->whereRaw('FIND_IN_SET(?, approval_job)', [$jobId]);
                            });
                        }
                    }
                }
            })->field(
                "id,user_id,operate,business_module,entity_id,child_business_module,child_entity_id,content,approval_job,approver,processed,process_time,create_time"
            );;
        $count = $query->count();
        $list = $query->page($pageIndex, $pageSize)
            ->order('processed asc,create_time desc')
            ->select()
            ->toArray();

        $list = $this->enrichBusinessLogs($list);
        return $this->success(['list' => $list, 'total' => $count]);
    }

    /**
     * @describe 已发起列表
     * @author: Bobo
     * @date: 2025-09-11 10:20:50
     * @param int $operator_id 操作员id
     * @param int $pageIndex 页码
     * @param int $pageSize 每页条数
     * @return Renderable
     */
    public function Initiated(int $operator_id, int $pageIndex, int $pageSize)
    {
        $query = Db::name('business_log')
            ->where('operate', 'in', $this->operate)
            ->where('user_id', $operator_id)
            ->field(
                "id,user_id,operate,business_module,entity_id,child_business_module,child_entity_id,content,approval_job,approver,processed,process_time,create_time"
            );

        $count = $query->count();
        $list = $query->page($pageIndex, $pageSize)
            ->order('processed asc,create_time desc')
            ->select()
            ->toArray();

        $list = $this->enrichBusinessLogs($list);
        return $this->success(['list' => $list, 'total' => $count]);
    }

    /**
     * @describe 富化业务日志
     * @author: Bobo
     * @date: 2025-09-11 10:20:50
     * @param array $list 业务日志列表
     * @return array 富化后的业务日志列表
     */
    private function enrichBusinessLogs(array $list): array
    {
        if (empty($list)) {
            return $list;
        }

        $all_user_ids = array_column($list, 'user_id');
        $all_user_ids = array_merge($all_user_ids, array_column($list, 'approver'));
        $all_user_ids = array_filter($all_user_ids, static function ($value) {
            return $value !== null && $value !== '';
        });
        $all_user_ids = array_values(array_unique($all_user_ids));
        $all_user = Db::name('operator')
            ->whereIn('id', $all_user_ids)
            ->field('id,cname')
            ->select()
            ->toArray();
        $all_user = array_column($all_user, 'cname', 'id');

        $operator = new OperatorModel();
        $jobList = $operator->getAttributesMap()['jobs'];

        $moduleMap = [
            'order' => '订单',
            'order_payment' => '回款单',
            'filingcabinet' => '文件柜',
            'order_part_delivery_apply' => '部分发货申请',
            'logistics_order' => '物流',
            'returnorder' => '退货退款单',
            'invoice' => '发票',
            'purchase_payment_order' => '采购单',
        ];

        foreach ($list as &$item) {
            $item['user_name'] = $all_user[$item['user_id']] ?? '';
            $item['approver'] =  $all_user[$item['approver']] ?? '';
            $item['processed'] = $item['processed'] ? '已处理' : '未处理';

            if (!empty($item['approval_job'])) {
                $jobIds = array_filter(explode(',', $item['approval_job']), 'strlen');
                $jobNames = [];
                foreach ($jobIds as $jobId) {
                    if (isset($jobList[$jobId])) {
                        $jobNames[] = $jobList[$jobId];
                    }
                }
                $item['approval_job'] = implode(',', $jobNames);
            }

            if (!empty($item['business_module']) && isset($moduleMap[$item['business_module']])) {
                $item['business_module'] = $moduleMap[$item['business_module']];
            }
        }

        return $list;
    }

    /**
     * @describe 已发起处理结果
     * @author: Bobo
     * @date: 2025-09-11 10:20:50
     * @param int $id 业务日志id
     * @return Renderable
     */
    public function InitiatedProcessedResult(int $id)
    {
        $businessLog = Db::name('business_log')
            ->where('id', $id)
            ->find();
        if (empty($businessLog)) {
            return $this->error(500001, '业务日志不存在');
        }
        if ($businessLog['processed'] == 1) {
            return $this->success(['result' => true]);
        }
        switch ($businessLog['operate']) {
            case '订单-编辑':
                $result = Db::name('order')
                    ->where('id', $businessLog['entity_id'])
                    ->find();
                if (20 == $result['status']) {
                    return $this->success(['result' => false]);
                } else {
                    return $this->success(['result' => true]);
                }
                break;
            case '订单-部分发货申请发起':
                $result = Db::name('order_part_delivery_apply')
                    ->where('id', $businessLog['child_entity_id'])
                    ->find();
                if (1 == $result['status']) {
                    return $this->success(['result' => false]);
                } else {
                    return $this->success(['result' => true]);
                }
                break;
            case '订单-支付凭证上传':
                $result = Db::name('order_payment')
                    ->where('id', $businessLog['child_entity_id'])
                    ->find();
                if ('00' == $result['status']) {
                    return $this->success(['result' => false]);
                } else {
                    return $this->success(['result' => true]);
                }
                break;
            case '退货退款单-创建':
                $result = Db::name('returnorder')
                    ->where('id', $businessLog['entity_id'])
                    ->find();
                if (1 == $result['status']) {
                    return $this->success(['result' => false]);
                } else {
                    return $this->success(['result' => true]);
                }
                break;
            case '发票-创建':
                $result = Db::name('invoice')
                    ->where('id', $businessLog['entity_id'])
                    ->find();
                if (1 == $result['status']) {
                    return $this->success(['result' => false]);
                } else {
                    return $this->success(['result' => true]);
                }
                break;
            case '采购付款单-创建':
                $result = Db::name('purchase_payment_order')  // 待确定审核状态
                    ->where('id', $businessLog['child_entity_id'])
                    ->find();
                if (1 == $result['status']) {
                    return $this->success(['result' => false]);
                } else {
                    return $this->success(['result' => true]);
                }
                break;
            case '库存-调拨发起':
                $result = Db::name('logistics_order')   // 待确定审核状态
                    ->where('id', $businessLog['child_entity_id'])
                    ->find();
                if (1 == $result['status']) {
                    return $this->success(['result' => false]);
                } else {
                    return $this->success(['result' => true]);
                }
                break;
            case '库存-校对发起':
                $result = Db::name('inventory')   // 待确定审核状态
                    ->where('id', $businessLog['child_entity_id'])
                    ->find();
                if (1 == $result['status']) {
                    return $this->success(['result' => false]);
                } else {
                    return $this->success(['result' => true]);
                }
                break;
        }

        return $this->success(['id' => $id]);
    }
}
